home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 14 / CU Amiga Magazine's Super CD-ROM 14 (1997)(EMAP Images)(GB)(Track 1 of 3)[!][issue 1997-09].iso / CUCD / Programming / Mesa-2.2 / demos / stex3d.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-03-04  |  15.6 KB  |  559 lines

  1. /*----------------------------- 
  2.  * stex3d.c GL example of the mesa 3d-texture extention to simulate procedural
  3.  *            texturing, it uses a perlin noise and turbulence functions.
  4.  * 
  5.  * Author:   Daniel Barrero
  6.  *           barrero@irit.fr
  7.  *           dbarrero@pegasus.uniandes.edu.co
  8.  *      
  9.  * cc stex3d.c -o stex3d -lMesaGLU -lMesaGL -lMesatk -lX11 -lXext -lm 
  10.  *
  11.  *---------------------------- */
  12.  
  13. #include <string.h>
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <math.h>
  17. #include <GL/gl.h>
  18. /*#include "gltkmesa.h"*/
  19. #include "gltk.h"
  20. /* function declarations */
  21. #ifndef M_PI
  22. #define M_PI            3.14159265358979323846
  23. #endif
  24.  
  25. void init(void),
  26.      printHelp(void),
  27.      create3Dtexture(void),
  28.      setDefaults(void),
  29.      drawScene(void),
  30.      resize(int w, int h),
  31.      buildFigure(void),
  32.      initNoise(void);
  33. float turbulence(float point[3], float lofreq, float hifreq);
  34.  
  35. int isExtSupported(char *ext);
  36. GLenum keyHandler(int key, GLenum mask),
  37.        parseCmdLine(int argc, char **argv);
  38. float noise3(float vec[3]);
  39.       
  40. /* global variables */
  41. GLenum rgb, doubleBuffer, directRender, windType; /* visualization state*/
  42. float tex_width,tex_height,tex_depth;        /* texture volume dimensions  */
  43. unsigned char *voxels;                       /* texture data ptr */
  44. int angx,angy,angz;
  45. GLuint figure;
  46.  
  47. /*function definitions */
  48. void main(int argc, char **argv)
  49. {
  50.  
  51.  if (parseCmdLine(argc, argv) == GL_FALSE) {
  52.     tkQuit();
  53.  }
  54.  
  55.  tkInitPosition(0, 0, 400, 400);
  56.  windType = (rgb) ? TK_RGB : TK_INDEX;
  57.  windType |= (doubleBuffer) ? TK_DOUBLE : TK_SINGLE;
  58.  windType |= (directRender) ? TK_DIRECT : TK_INDIRECT;
  59.  windType |= TK_DEPTH;
  60.  tkInitDisplayMode(windType);
  61.  
  62.  if (tkInitWindow("stex3d") == GL_FALSE) {
  63.      tkQuit();
  64.  }
  65.  /* init all */
  66.  init();
  67.  
  68.  tkExposeFunc(resize);
  69.  tkReshapeFunc(resize);
  70.  tkKeyDownFunc(keyHandler);
  71.  tkDisplayFunc(drawScene);
  72.  tkExec();
  73. }
  74.  
  75. void init()
  76.  /* init light */
  77.  GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
  78.  GLfloat mat_shininess[] = { 25.0 };
  79.  GLfloat gray[] = { 0.6, 0.6, 0.6, 0.0 };
  80.  GLfloat white[] = { 1.0, 1.0, 1.0, 0.0 };
  81.  GLfloat light_position[] = { 0.0, 1.0, 1.0, 0.0 };
  82.  
  83.  glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
  84.  glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
  85.  glLightfv(GL_LIGHT1, GL_POSITION, light_position);
  86.  glLightfv(GL_LIGHT1, GL_AMBIENT, gray);
  87.  glLightfv(GL_LIGHT1, GL_DIFFUSE, white);
  88.  glLightfv(GL_LIGHT1, GL_SPECULAR, white);
  89.  glColorMaterial(GL_FRONT, GL_DIFFUSE);
  90.  glEnable(GL_COLOR_MATERIAL);
  91.  glEnable(GL_LIGHTING);
  92.  glEnable(GL_LIGHT1);
  93.  
  94.  /* create torus for texturing */
  95.  figure=glGenLists(1); 
  96.  buildFigure();
  97. /* tkSolidTorus(figure,0.3,1.2);*/
  98.  
  99.  /* start the noise function variables */
  100.  initNoise();
  101.  
  102.  /* see if the texture 3d extention is supported */
  103.  if (!isExtSupported("GL_EXT_texture3D")) {
  104.    printf("Sorry this GL implementation (%s) does not support 3d texture extentions\n",
  105.         (char *)(glGetString(GL_RENDERER)));
  106. /*   tkQuit();*/
  107.  }
  108.  
  109.  /* if texture is supported then generate the texture */
  110.  create3Dtexture(); 
  111.  
  112.  glEnable(GL_TEXTURE_3D_EXT); 
  113.  /*
  114.  glBlendFunc(GL_SRC_COLOR, GL_SRC_ALPHA);
  115.  glEnable(GL_BLEND); 
  116.  */
  117.  glEnable(GL_DEPTH_TEST);
  118.  
  119.  glShadeModel(GL_FLAT);
  120.  glColor3f(0.6,0.7,0.8);
  121. }
  122.  
  123. void buildFigure(void)
  124. {   GLint i, j;
  125.     float theta1, phi1, theta2, phi2, rings, sides;
  126.     float v0[03], v1[3], v2[3], v3[3];
  127.     float t0[03], t1[3], t2[3], t3[3];
  128.     float n0[3], n1[3], n2[3], n3[3];
  129.     float innerRadius=0.4;
  130.     float outerRadius=0.8;
  131.     float scalFac;
  132.  
  133.     rings = 8;
  134.     sides = 10;
  135.     scalFac=1/(outerRadius*2);
  136.  
  137.     glNewList(figure, GL_COMPILE);
  138.     for (i = 0; i < rings; i++) {
  139.         theta1 = (float)i * 2.0 * M_PI / rings;
  140.         theta2 = (float)(i + 1) * 2.0 * M_PI / rings;
  141.         for (j = 0; j < sides; j++) {
  142.             phi1 = (float)j * 2.0 * M_PI / sides;
  143.             phi2 = (float)(j + 1) * 2.0 * M_PI / sides;
  144.  
  145.             v0[0] = cos(theta1) * (outerRadius + innerRadius * cos(phi1));
  146.             v0[1] = -sin(theta1) * (outerRadius + innerRadius * cos(phi1));
  147.             v0[2] = innerRadius * sin(phi1);
  148.  
  149.             v1[0] = cos(theta2) * (outerRadius + innerRadius * cos(phi1));
  150.             v1[1] = -sin(theta2) * (outerRadius + innerRadius * cos(phi1));
  151.             v1[2] = innerRadius * sin(phi1);
  152.             v2[0] = cos(theta2) * (outerRadius + innerRadius * cos(phi2));
  153.             v2[1] = -sin(theta2) * (outerRadius + innerRadius * cos(phi2));
  154.             v2[2] = innerRadius * sin(phi2);
  155.  
  156.             v3[0] = cos(theta1) * (outerRadius + innerRadius * cos(phi2));
  157.             v3[1] = -sin(theta1) * (outerRadius + innerRadius * cos(phi2));
  158.             v3[2] = innerRadius * sin(phi2);
  159.  
  160.             n0[0] = cos(theta1) * (cos(phi1));
  161.             n0[1] = -sin(theta1) * (cos(phi1));
  162.             n0[2] = sin(phi1);
  163.  
  164.             n1[0] = cos(theta2) * (cos(phi1));
  165.             n1[1] = -sin(theta2) * (cos(phi1));
  166.             n1[2] = sin(phi1);
  167.  
  168.             n2[0] = cos(theta2) * (cos(phi2));
  169.             n2[1] = -sin(theta2) * (cos(phi2));
  170.             n2[2] = sin(phi2);
  171.  
  172.             n3[0] = cos(theta1) * (cos(phi2));
  173.             n3[1] = -sin(theta1) * (cos(phi2));
  174.             n3[2] = sin(phi2);
  175.  
  176.             t0[0] = v0[0]*scalFac + 0.5;
  177.             t0[1] = v0[1]*scalFac + 0.5;
  178.             t0[2] = v0[2]*scalFac + 0.5;
  179.  
  180.             t1[0] = v1[0]*scalFac + 0.5;
  181.             t1[1] = v1[1]*scalFac + 0.5;
  182.             t1[2] = v1[2]*scalFac + 0.5;
  183.  
  184.             t2[0] = v2[0]*scalFac + 0.5;
  185.             t2[1] = v2[1]*scalFac + 0.5;
  186.             t2[2] = v2[2]*scalFac + 0.5;
  187.  
  188.             t3[0] = v3[0]*scalFac + 0.5;
  189.             t3[1] = v3[1]*scalFac + 0.5;
  190.             t3[2] = v3[2]*scalFac + 0.5;
  191.  
  192.             glBegin(GL_POLYGON);
  193.                 glNormal3fv(n3); glTexCoord3fv(t3); glVertex3fv(v3);
  194.                 glNormal3fv(n2); glTexCoord3fv(t2); glVertex3fv(v2);
  195.                 glNormal3fv(n1); glTexCoord3fv(t1); glVertex3fv(v1);
  196.                 glNormal3fv(n0); glTexCoord3fv(t0); glVertex3fv(v0);
  197.             glEnd();
  198.         }
  199.     }
  200.     glEndList();
  201. }
  202.  
  203. void create3Dtexture()
  204. {
  205.  int i,j,k;
  206.  unsigned char *vp;
  207.  float vec[3];
  208.  int tmp;
  209.  
  210.  printf("creating 3d textures...\n");
  211.  voxels = (unsigned char  *) malloc((4*tex_width*tex_height*tex_depth));
  212.  vp=voxels;
  213.  for (i=0;i<tex_width;i++){
  214.     vec[0]=i;
  215.     for (j=0;j<tex_height;j++) {
  216.       vec[1]=j;
  217.        for (k=0;k<tex_depth;k++) {
  218.            vec[2]=k;
  219.            tmp=(sin(k*i*j+turbulence(vec,0.01,1))+1)*127.5; 
  220.            *vp++=0;
  221.            *vp++=0;
  222.            *vp++=tmp; 
  223.            *vp++=tmp+128; 
  224.        }
  225.      }
  226.  }
  227.  
  228.  printf("setting up 3d texture...\n");
  229.  glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  230.  glTexParameteri(GL_TEXTURE_3D_EXT, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  231.  glTexParameteri(GL_TEXTURE_3D_EXT, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  232.  glTexParameteri(GL_TEXTURE_3D_EXT, GL_TEXTURE_WRAP_S,     GL_REPEAT);
  233.  glTexParameteri(GL_TEXTURE_3D_EXT, GL_TEXTURE_WRAP_T,     GL_REPEAT);
  234.  glTexParameteri(GL_TEXTURE_3D_EXT, GL_TEXTURE_WRAP_R_EXT, GL_REPEAT);
  235.  glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
  236.  
  237.  glTexImage3DEXT(GL_TEXTURE_3D_EXT, 0, GL_RGBA,
  238.                     tex_width, tex_height, tex_depth,
  239.                     0, GL_RGBA, GL_UNSIGNED_BYTE, voxels);
  240.  
  241.  printf("finished setting up 3d texture image...\n");
  242. }
  243.  
  244. int isExtSupported(char *ext)
  245. {
  246.     /* routine to find whether a specified OpenGL extension is supported */
  247.  
  248.     char *c;
  249.     int len;
  250.     char *allext = (char *)(glGetString(GL_EXTENSIONS));
  251.  
  252.     len = strlen(ext);
  253.     if (len <= 0) return 0;
  254.  
  255.     c = allext;
  256.     while (c) {
  257.         if (!strncmp(c,ext,len)) return 1;
  258.         c = strchr(c+1,'G');
  259.     }
  260.     return 0;
  261. }
  262.  
  263. void printHelp()
  264. {
  265.   printf("\nUsage: stex3d  <cmd line options>\n"); 
  266.   printf(" cmd line options:\n");
  267.   printf("      -help   print this help!\n");
  268.   printf("     -rgb     RGBA mode. (Default)\n");
  269.   printf("      -ci     Color index mode.\n");
  270.   printf("      -sb     Single buffer mode. (Default)\n");
  271.   printf("      -db     Double buffer mode. \n");
  272.   printf("      -dr     Direct render mode.\n");
  273.   printf("      -ir     Indirect render mode. (Default)\n");
  274.   printf("      -wxxx   Width of the texture (Default=64)\n");
  275.   printf("      -hxxx   Height of the texture (Default=64)\n");
  276.   printf("      -dxxx   Depth of the texture (Default=64)\n");
  277.   printf(" Keyboard Options:\n");
  278.   printf("       1      Object Texture coordinates (Default)\n");
  279.   printf("       2      Eye Texture coordinates \n");
  280.   printf("       x      rotate around x clockwise\n");
  281.   printf("       X      rotate around x counter clockwise\n");
  282.   printf("       y      rotate around y clockwise\n");
  283.   printf("       Y      rotate around y counter clockwise\n");
  284.   printf("       z      rotate around z clockwise\n");
  285.   printf("       Z      rotate around z counter clockwise\n");
  286.   printf("       t      enable 3-D texuring (Default)\n");
  287.   printf("       T      disable 3-D texuring\n");
  288.   printf("       s      smooth shading \n");
  289.   printf("       S      flat shading (Default)\n");
  290. }
  291.  
  292. void setDefaults()
  293. {
  294.  /* visualization defaults */
  295.   rgb = GL_TRUE;
  296.   doubleBuffer = GL_FALSE;
  297.   directRender = GL_TRUE;
  298.   angx=130;
  299.   angy=30;
  300.   angz=0; 
  301.  /* texture values */
  302.  tex_width=64;
  303.  tex_height=64;
  304.  tex_depth=64;
  305. }
  306.  
  307. GLenum parseCmdLine(int argc, char **argv)
  308. {
  309.   GLint i;
  310.  
  311.   setDefaults();
  312.  
  313.   for (i = 1; i < argc; i++) {
  314.       if (strcmp(argv[i], "-ci") == 0) {
  315.           rgb = GL_FALSE;
  316.       } else if (strcmp(argv[i], "-rgb") == 0) {
  317.           rgb = GL_TRUE;
  318.       } else if (strcmp(argv[i], "-sb") == 0) {
  319.           doubleBuffer = GL_FALSE;
  320.       } else if (strcmp(argv[i], "-db") == 0) {
  321.           doubleBuffer = GL_TRUE;
  322.       } else if (strcmp(argv[i], "-dr") == 0) {
  323.           directRender = GL_TRUE;
  324.       } else if (strcmp(argv[i], "-ir") == 0) {
  325.           directRender = GL_FALSE;
  326.       } else if (strstr(argv[i], "-w") == 0) {
  327.           tex_width=atoi((argv[i])+2);
  328.       } else if (strstr(argv[i], "-h") == 0) {
  329.           tex_height=atoi((argv[i])+2);
  330.       } else if (strstr(argv[i], "-d") == 0) {
  331.           tex_depth=atoi((argv[i])+2);
  332.       } else if (strcmp(argv[i], "-help") == 0) {
  333.           printHelp();
  334.           return GL_FALSE;
  335.       } else {
  336.           printf("%s (Bad option).\n", argv[i]);
  337.           printHelp();
  338.           return GL_FALSE;
  339.       }
  340.   }
  341.  if(tex_width==0 || tex_height==0 || tex_depth==0) {
  342.    printf("%s (Bad option).\n", "size parameters can't be 0");
  343.    printHelp();
  344.    return GL_FALSE;
  345.  }
  346.   return GL_TRUE;
  347. }
  348.  
  349. void drawScene()
  350. {
  351.  /* clear background, z buffer etc */
  352.  glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  353.  glPushMatrix();
  354.  glRotatef(angx,1.0,0.0,0.0);
  355.  glRotatef(angy,0.0,1.0,0.0);
  356.  glRotatef(angz,0.0,0.0,1.0);
  357.  
  358.  glCallList(figure);     
  359.  glPopMatrix();
  360.  glFlush();
  361.  if(doubleBuffer)
  362.    tkSwapBuffers();
  363.  ;
  364. }
  365.  
  366. void resize(int w, int h)
  367.  glViewport(0, 0, (GLint)w, (GLint)h);
  368.  glMatrixMode(GL_PROJECTION);
  369.  glLoadIdentity();
  370.  glOrtho(-2,2,-2,2,-5,10);
  371.  glMatrixMode(GL_MODELVIEW);
  372.  glLoadIdentity();
  373.  glTranslatef(0,0,-5);
  374. }
  375.  
  376. void cleanEverything()
  377. {
  378. /*  free(voxels); */
  379. }
  380.  
  381. GLenum keyHandler(int key, GLenum mask)
  382. {
  383.  switch(key) {
  384.       case TK_ESCAPE:
  385.    case TK_q:
  386.    case TK_Q: /* quit game. */
  387.           cleanEverything();
  388.            tkQuit();
  389.            break;
  390.    case TK_x:
  391.            angx+=10;
  392.            break;
  393.    case TK_X: 
  394.            angx-=10; 
  395.            break;
  396.    case TK_y:
  397.            angy+=10;
  398.            break;
  399.    case TK_Y: 
  400.            angy-=10; 
  401.            break;
  402.    case TK_z:
  403.            angz+=10;
  404.            break;
  405.    case TK_Z: 
  406.            angz-=10; 
  407.            break;
  408.    case TK_t:
  409.            glEnable(GL_TEXTURE_3D_EXT); 
  410.            break;
  411.    case TK_T:
  412.            glDisable(GL_TEXTURE_3D_EXT);
  413.            break;
  414.    case TK_s:
  415.            glShadeModel(GL_SMOOTH);
  416.            break;
  417.    case TK_S:
  418.            glShadeModel(GL_FLAT);
  419.            break;
  420.    case TK_1:
  421.            glDisable(GL_TEXTURE_GEN_S);
  422.            glDisable(GL_TEXTURE_GEN_T);
  423.            glDisable(GL_TEXTURE_GEN_R);
  424.            break;
  425.    case TK_2:
  426.            glEnable(GL_TEXTURE_GEN_S);
  427.            glEnable(GL_TEXTURE_GEN_T);
  428.            glEnable(GL_TEXTURE_GEN_R);
  429.            break;
  430.    default:
  431.      break;
  432.  }
  433.  return GL_TRUE;
  434. }
  435.  
  436. /*--------------------------------------------------------------------
  437.  noise function over R3 - implemented by a pseudorandom tricubic spline 
  438.               EXCERPTED FROM SIGGRAPH 92, COURSE 23
  439.                         PROCEDURAL MODELING
  440.                              Ken Perlin
  441.                            New York University
  442. ----------------------------------------------------------------------*/
  443.  
  444.  
  445. #define DOT(a,b) (a[0] * b[0] + a[1] * b[1] + a[2] * b[2])
  446. #define B 256
  447. static int p[B + B + 2];
  448. static float g[B + B + 2][3];
  449. #define setup(i,b0,b1,r0,r1) \
  450.         t = vec[i] + 10000.; \
  451.         b0 = ((int)t) & (B-1); \
  452.         b1 = (b0+1) & (B-1); \
  453.         r0 = t - (int)t; \
  454.         r1 = r0 - 1.;
  455.  
  456. float noise3(float vec[3])
  457. {
  458.         int bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11;
  459.         float rx0, rx1, ry0, ry1, rz0, rz1, *q, sx, sy, sz, a, b, c, d, t, u, v;
  460.         register i, j;
  461.  
  462.         setup(0, bx0,bx1, rx0,rx1);
  463.         setup(1, by0,by1, ry0,ry1);
  464.         setup(2, bz0,bz1, rz0,rz1);
  465.  
  466.         i = p[ bx0 ];
  467.         j = p[ bx1 ];
  468.  
  469.         b00 = p[ i + by0 ];
  470.         b10 = p[ j + by0 ];
  471.         b01 = p[ i + by1 ];
  472.         b11 = p[ j + by1 ];
  473.  
  474. #define at(rx,ry,rz) ( rx * q[0] + ry * q[1] + rz * q[2] )
  475. #define surve(t) ( t * t * (3. - 2. * t) )
  476. #define lerp(t, a, b) ( a + t * (b - a) )
  477.  
  478.         sx = surve(rx0);
  479.         sy = surve(ry0);
  480.         sz = surve(rz0);
  481.  
  482.         q = g[ b00 + bz0 ] ; u = at(rx0,ry0,rz0);
  483.         q = g[ b10 + bz0 ] ; v = at(rx1,ry0,rz0);
  484.         a = lerp(sx, u, v);
  485.  
  486.         q = g[ b01 + bz0 ] ; u = at(rx0,ry1,rz0);
  487.         q = g[ b11 + bz0 ] ; v = at(rx1,ry1,rz0);
  488.         b = lerp(sx, u, v);
  489.  
  490.         c = lerp(sy, a, b);          /* interpolate in y at lo x */
  491.  
  492.         q = g[ b00 + bz1 ] ; u = at(rx0,ry0,rz1);
  493.         q = g[ b10 + bz1 ] ; v = at(rx1,ry0,rz1);
  494.         a = lerp(sx, u, v);
  495.  
  496.         q = g[ b01 + bz1 ] ; u = at(rx0,ry1,rz1);
  497.         q = g[ b11 + bz1 ] ; v = at(rx1,ry1,rz1);
  498.         b = lerp(sx, u, v);
  499.  
  500.         d = lerp(sy, a, b);          /* interpolate in y at hi x */
  501.  
  502.         return 1.5 * lerp(sz, c, d); /* interpolate in z */
  503. }
  504.  
  505. void initNoise()
  506. {
  507.         long random();
  508.         int i, j, k;
  509.         float v[3], s;
  510.  
  511. /* Create an array of random gradient vectors uniformly on the unit sphere */
  512.         srandom(1);
  513.         for (i = 0 ; i < B ; i++) {
  514.                 do {                            /* Choose uniformly in a cube */                        for (j=0 ; j<3 ; j++)
  515.                                 v[j] = (float)((random() % (B + B)) - B) / B;
  516.                         s = DOT(v,v);
  517.                 } while (s > 1.0);              /* If not in sphere try again */                s = sqrt(s);
  518.                 for (j = 0 ; j < 3 ; j++)       /* Else normalize */
  519.                         g[i][j] = v[j] / s;
  520.         }
  521.  
  522. /* Create a pseudorandom permutation of [1..B] */
  523.         for (i = 0 ; i < B ; i++)
  524.                 p[i] = i;
  525.         for (i = B ; i > 0 ; i -= 2) {
  526.                 k = p[i];
  527.                 p[i] = p[j = random() % B];
  528.                 p[j] = k;
  529.         }
  530.  
  531. /* Extend g and p arrays to allow for faster indexing */
  532.         for (i = 0 ; i < B + 2 ; i++) {
  533.                 p[B + i] = p[i];
  534.                 for (j = 0 ; j < 3 ; j++)
  535.                         g[B + i][j] = g[i][j];
  536.         }
  537. }
  538.  
  539. float turbulence(float point[3], float lofreq, float hifreq)
  540. {
  541.         float freq, t, p[3];
  542.  
  543.         p[0] = point[0] + 123.456;
  544.         p[1] = point[1];
  545.         p[2] = point[2];
  546.  
  547.         t = 0;
  548.         for (freq = lofreq ; freq < hifreq ; freq *= 2.) {
  549.                 t += fabs(noise3(p)) / freq;
  550.                 p[0] *= 2.;
  551.                 p[1] *= 2.;
  552.                 p[2] *= 2.;
  553.         }
  554.         return t - 0.3; /* readjust to make mean value = 0.0 */
  555. }
  556.  
  557.